package com.tlgen.modules.vocation.service.impl;

import com.tlgen.common.exception.EntityExistException;
import com.tlgen.common.utils.*;
import com.tlgen.modules.vocation.domain.Home;
import com.tlgen.modules.vocation.domain.HomeFile;
import com.tlgen.modules.vocation.repository.HomeFileRepository;
import com.tlgen.modules.vocation.repository.HomeRepository;
import com.tlgen.modules.vocation.service.HomeService;
import com.tlgen.modules.vocation.service.dto.HomeDto;
import com.tlgen.modules.vocation.service.dto.HomeQueryCriteria;
import com.tlgen.modules.vocation.service.mapper.HomeMapper;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.*;

@Service
@CacheConfig(cacheNames = "Home")
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class HomeServiceImpl implements HomeService {

    private final HomeRepository homeRepository;

    private final HomeMapper HomeMapper;

    private final HomeFileRepository homeFileRepository;


    @Value("${file.homefile}")
    private String homefile;

    public HomeServiceImpl(HomeRepository homeRepository, HomeMapper homeMapper, HomeFileRepository homeFileRepository) {
        this.homeRepository = homeRepository;
        this.HomeMapper = homeMapper;
        this.homeFileRepository = homeFileRepository;
    }


    @Override
    @Cacheable(key = "'tree'")
    public Object getHomeTree(List<Home> homes) {
        List<Map<String, Object>> list = new LinkedList<>();
        homes.forEach(home -> {
            if (home != null) {
                List<Home> homeList = homeRepository.findByPid(home.getId());
                Map<String, Object> map = new HashMap<>(16);
                map.put("id", home.getId());
                map.put("label", home.getName());
                if (homeList != null && homeList.size() != 0) {
                    map.put("children", getHomeTree(homeList));
                }
                list.add(map);
            }
        });
        return list;
    }

    @Override
    @Cacheable(key = "'pid:'+#p0")
    public List<Home> findByPid(long pid) {
        return homeRepository.findByPid(pid);
    }

    /**
     * 不带条件分页查询
     * @param pageable 分页参数
     * @return
     */
    @Override
    @Cacheable
    public Object queryAll(Pageable pageable) {
        return HomeMapper.toDto(homeRepository.findAll(pageable).getContent());
    }


    /**
     * 带条件分页查询
     * @param criteria 条件
     * @param pageable 分页参数
     * @return
     */
    @Override
    @Cacheable
    public Object queryAll(HomeQueryCriteria criteria, Pageable pageable) {
        Page<Home> page = homeRepository.findAll((root, criteriaQuery, criteriaBuilder) ->
                QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
        return PageUtil.toPage(page.map(HomeMapper::toDto));
    }

    /**
     * 带条件不分页查询
     * @param criteria 条件
     * @return
     */
    @Override
    @Cacheable
    public List<HomeDto> queryAll(HomeQueryCriteria criteria) {
        return HomeMapper.toDto(homeRepository.findAll((root, criteriaQuery, criteriaBuilder) ->
                QueryHelp.getPredicate(root,criteria,criteriaBuilder)));
    }

    /**
     * 新增
     * @param resources /
     * @return
     */
    @Override
    @CacheEvict(allEntries = true)
    @Transactional(rollbackFor = Exception.class)
    public HomeDto create(Home resources) {
        if(homeRepository.findByName(resources.getName()) != null){
            throw new EntityExistException(Home.class, "attr", resources.getAttr());
        }
        return HomeMapper.toDto(homeRepository.save(resources));
    }

    /**
     * 编辑
     * @param resources /
     */
    @Override
    @CacheEvict(allEntries = true)
    @Transactional(rollbackFor = Exception.class)
    public void update(Home resources) {
        Home home = homeRepository.findById(resources.getId()).orElseGet(Home::new);
        ValidationUtil.isNull(home.getId(),"Home","id",resources.getId());

        Home home1 = homeRepository.findByName(resources.getName());

        if(home1 != null && !home1.getId().equals(home.getId())){
            throw new EntityExistException(Home.class,"Home",resources.getAttr());
        }

        home.setCode(resources.getCode());
        home.setName(resources.getName());
        home.setCard(resources.getCard());
        home.setSex(resources.getSex());
        home.setNation(resources.getNation());
        home.setHeath(resources.getHeath());
        home.setCulture(resources.getCulture());
        home.setAttr(resources.getAttr());
        home.setIsfarm(resources.getIsfarm());
        home.setWedding(resources.getWedding());
        home.setPosition(resources.getPosition());
        home.setTelephone(resources.getTelephone());
        home.setFarmid(resources.getFarmid());
        home.setIscountry(resources.getIscountry());
        home.setCSort(resources.getCSort());
        home.setStarttime(resources.getStarttime());
        home.setEndtime(resources.getEndtime());
        home.setEnabled(resources.getEnabled());
        home.setJ_area(resources.getJ_area());
        home.setJ_area_out(resources.getJ_area_out());
        home.setHomeFile(resources.getHomeFile());
        home.setPaycode(resources.getPaycode());
        home.setPaystarttime(resources.getPaystarttime());
        home.setPayendtime(resources.getPayendtime());
        home.setIsconsult(resources.getIsconsult());
        home.setIspay(resources.getIspay());
        home.setAmount(resources.getAmount());
        home.setPaytype(resources.getPaytype());
        home.setPaytime(resources.getPaytime());
        home.setNowamount(resources.getNowamount());
        home.setAccountname(resources.getAccountname());
        home.setAccountamount(resources.getAccountamount());
        homeRepository.save(home);
    }

    /**
     * 根据Id查询
     * @param id /
     * @return
     */
    @Override
    @Cacheable(key = "#p0")
    public HomeDto findById(long id) {
        Home Home = homeRepository.findById(id).orElseGet(Home::new);
        ValidationUtil.isNull(Home.getId(),"Home","id",id);
        return HomeMapper.toDto(Home);
    }

    /**
     * 删除
     * @param ids /
     */
    @Override
    @CacheEvict(allEntries = true)
    @Transactional(rollbackFor = Exception.class)
    public void delete(Set<Long> ids) {
        for (Long id : ids) {
            homeRepository.deleteById(id);
        }
    }

    /**
     * 导出数据
     * @param response /
     * @throws IOException
     */
    @Override
    public void download(List<HomeDto> homeDtos, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (HomeDto homeDto : homeDtos) {
            Map<String,Object> map = new LinkedHashMap<>();
            map.put("户内编号", homeDto.getCode());
            map.put("户主姓名", homeDto.getName());
            map.put("身份证号", homeDto.getCard());
            map.put("性别", homeDto.getSex());
            map.put("民族", homeDto.getNation());
            map.put("健康状态", homeDto.getHeath());
            map.put("文化程度", homeDto.getCulture());
            map.put("人员属性", homeDto.getAttr());
            map.put("是否农业户口", homeDto.getIsfarm());
            map.put("婚姻情况", homeDto.getWedding());
            map.put("岗位", homeDto.getPosition());
            map.put("电话号码", homeDto.getTelephone());
            map.put("农合证号", homeDto.getFarmid());
            map.put("是否农村户口", homeDto.getIscountry());
            map.put("工作单位", homeDto.getWork());
            map.put("慢性病", homeDto.getCSort());
            map.put("慢性病开始时间", homeDto.getStarttime());
            map.put("慢性病结束时间", homeDto.getEndtime());
            map.put("是否通过审核", homeDto.getEnabled());
            map.put("所在区域名称", homeDto.getJ_area());
            map.put("附件", homeDto.getHomeFile().getRealName());
            map.put("支付编号", homeDto.getPaycode());
            map.put("规定的缴费起始时间", homeDto.getPaystarttime());
            map.put("规定的最终缴费时间", homeDto.getPayendtime());
            map.put("是否参合", homeDto.getIsconsult());
            map.put("是否支付", homeDto.getIspay());
            map.put("支付金额", homeDto.getAmount());
            map.put("支付方式", homeDto.getPaytype());
            map.put("支付时间", homeDto.getPaytime());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }

    /**
     * 上传附件
     * @param multipartFile
     */
    @Override
    @CacheEvict(allEntries = true)
    @Transactional(rollbackFor = Exception.class)
    public void uploadFile(MultipartFile multipartFile) {
        File file = FileUtil.upload(multipartFile, homefile);
        assert file != null;
        HomeFile homeFile = new HomeFile(file.getName(), file.getPath(), FileUtil.getSize(multipartFile.getSize()));
        homeFileRepository.save(homeFile);
    }


}
